/*
 * @(#)XfspRulebaseSimplifierDirector.java        2004/08/01
 *
 * This file is part of Xfuzzy 3.1, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfsp.model.rulebases;

import xfuzzy.lang.Rule;
import xfuzzy.lang.KnowledgeBase;
import xfuzzy.lang.RuleSet;
import xfuzzy.lang.Specification;

/**
 * <p> <b>Descripci�n:</b> simplificador de bases de reglas que permite
 * transformar las en otras equivalentes por compactaci�n o expansi�n de las
 * mismas.
 * <p> <b>E-mail</b>: <ADDRESS>joragupra@us.es</ADDRRESS>
 * @author Jorge Agudo Praena
 * @version 2.0
 * @see XfspModel
 * @see IXfspRulebaseSimplifier
 *
 */
public class XfspRulebaseSimplifierDirector
    implements IXfspRulebaseSimplifier {

  //conversor de reglas a otras equivalentes
  private XfspRuleConverter conv;

  //nueva base de reglas equivalente a la original
  private KnowledgeBase newrb;

  //tipo de conversi�n que se har� de la base de reglas original
  private String type;

  /**
   * <p> <b>Descripci�n:</b> crea un simplificador de bases de reglas que
   * realiza la conversi�n de una base de reglas a otra equivalente por los
   * m�todos de compactaci�n o de expansi�n.
   * @param type M�todo de conversi�n de bases de reglas que se emplear�. Puede
   * ser compactaci�n o expansi�n de la base de reglas original.
   *
   */
  public XfspRulebaseSimplifierDirector(String type) {
    //establece el tipo de conversi�n que se llevar� a cabo
    this.type = type;
  }

  /**
   * <p> <b>Descripci�n:</b> simplifica una base de reglas de un sistem difuso
   * cuya especificaci�n tambi�n es proporcionada.
   * @param rulebase Base de reglas que se quiere simplificar.
   * @param spec Especificaci�n del sistema cuya base de reglas se va a
   * simplificar.
   *
   */
  public void simplify(KnowledgeBase rulebase, Specification spec) {
    //construye la nueva base de reglas a partir de la original
    newrb = build(this.type, rulebase);
    //cambia en la especificaci�n del sistema la base de reglas original por la
    //nueva
    spec.exchangeRulebase(rulebase, newrb);
    //elimina todas las reglas de la base de reglas original...
    rulebase.removeAllRules();
    //...y le a�ade las reglas de la base nueva
    for (int i = 0; i < ((RuleSet) newrb).getRules().length; i++) {
    	((RuleSet) rulebase).addRule(((RuleSet) newrb).getRules()[i]);
    }
  }

  /**
   * <p> <b>Descripci�n:</b> construye una nueva base de reglas a partir de la
   * primera y equivalente a la misma.
   * @param type Tipo de base de reglas que se va a construir. �ste puede ser
   * una base de reglas compactada o expandida.
   * @param rulebase Base de reglas original a partir de la cual se construir�
   * otra equivalente.
   *
   */
  public KnowledgeBase build(String type, KnowledgeBase rulebase) {
    //clona la base de reglas original
    newrb = (KnowledgeBase) rulebase.clone();
    //crea un objeto que convierte reglas en otras equivalentes seg�n el tipo
    //indicado
    conv = XfspRuleConverter.create(type, newrb);
    //obtiene las reglas de la base de reglas
    Rule[] rules = ((RuleSet) newrb).getRules();
    //para cada una de las reglas de la base de reglas...
    for (int i = 0; i < rules.length; i++) {
      Rule rule = rules[i];
      //...se la pasa al conversor de reglas para que la transforme en otra
      //equivalente
      conv.buildRule(rule);
    }
    //obtiene la base de reglas equivalente a la original que ha construido el
    //conversor de bases de reglas
    newrb = conv.getRulebase();
    //devuelve la nueva base de reglas
    return newrb;
  }
}
